package com.pci.netty.handler;

import cn.hutool.crypto.digest.DigestUtil;
import com.pci.netty.dto.RequestPayload;
import com.pci.netty.util.AESUtils;
import com.pci.netty.util.ResponseUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.util.concurrent.EventExecutorGroup;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;

@Slf4j
public class Line18ControlDecode extends LengthFieldBasedFrameDecoder {

    private final static int HEAD_SIZE = 4;
    private final static int FIXED_LEN = 32;
    private final static int BODY_LEN = 32;

    public Line18ControlDecode(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength) {
        super(maxFrameLength, lengthFieldOffset, lengthFieldLength);
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {

        ByteBuf frame = (ByteBuf) super.decode(ctx, in);
        if (frame == null) {
            return null;
        }
        try {
            log.info(ByteBufUtil.prettyHexDump(frame));
            if (frame.readableBytes() < BODY_LEN) {
                log.error("报文长度不足");
                return null;
            }
            int length = frame.readInt();
            if(length!=frame.readableBytes()){
                log.error("报文标记的长度与报文实际长度不符！");
                return null;
            }
            byte[] data = new byte[length - 16];//包头和包体
            byte[] check = new byte[16];//校验码
            frame.readBytes(data);
            frame.readBytes(check);

            //md5校验
            if (!Arrays.equals(DigestUtil.md5(data),check)) {
                ResponseUtils.dataError(data, ctx);
                return null;
            }
            //包体为null
            if(length==BODY_LEN){
                return new RequestPayload(data,null,new String(check));
            }else{
                int bodyLength = data.length - 16;
                byte[] head=new byte[16];
                byte[] body=new byte[bodyLength];
                System.arraycopy(data, 0, head, 0, 16);
                System.arraycopy(data, 16, body, 0, bodyLength);
                //aes解密
                String content = AESUtils.decrypt(body);
                if (content == null) {
                    //aes解密失败
                    ResponseUtils.dataError(head, body, ctx);
                    return null;
                }
                return new RequestPayload(head, content, new String(check));
            }


        } catch (Exception e) {

        }
        return null;
    }
}
